package com.aivin.lib_widget;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;


/**
 * 具有从左到右滑动页面的控件。
 * 也就是负一屏效果
 * 源码拷贝自
 * https://github.com/hnyer/SecondaryScreen/blob/master/app/src/main/java/com/zhl/secondaryscreen/view/SecondaryScreenView.java
 */
public class WithLeftScreenViewGroup extends ViewGroup {

    // region 变量
    /**
     * 负一层的布局 getChildAt(0)
     */
    private View secondaryView;
    /**
     *  第一层的布局， getChildAt(1)
     */
    private View mainView;
    /**
     * 手指触摸和离开是 x 的坐标
     */
    private int downX,   endX;
    /**
     * 用来调节滑动灵敏度的参数
     */
    private float rate = 1f;

    // endregion

    // region 构造函数
    public WithLeftScreenViewGroup(Context context) {
        this(context, null);
    }

    public WithLeftScreenViewGroup(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public WithLeftScreenViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    // endregion



    // region 绘制、布局相关
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int count = getChildCount();
        if (count !=2) {
            throw new RuntimeException("must be host 2 direct child view");
        }
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int usedWidth = 0;
        int usedHeight = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View childView = getChildAt(i);
            if (childView.getVisibility() != View.GONE) {
                WithLeftScreenViewGroup.LayoutParams params = (WithLeftScreenViewGroup.LayoutParams) childView.getLayoutParams();
                int childWidthSpec;
                int childHeightSpec;
                switch (params.width) {
                    case WithLeftScreenViewGroup.LayoutParams.MATCH_PARENT:
                        if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST) {
                            childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
                        } else {
                            childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                        }
                        break;
                    case WithLeftScreenViewGroup.LayoutParams.WRAP_CONTENT:
                        if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST) {
                            childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
                        } else {
                            childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                        }
                        break;
                    default:
                        childWidthSpec = MeasureSpec.makeMeasureSpec(params.width, MeasureSpec.EXACTLY);
                        break;
                }
                usedWidth += MeasureSpec.getSize(childWidthSpec) + params.leftMargin + params.rightMargin;
                switch (params.height) {
                    case WithLeftScreenViewGroup.LayoutParams.MATCH_PARENT:
                        if (heightMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.AT_MOST) {
                            childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
                        } else {
                            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                        }
                        break;
                    case WithLeftScreenViewGroup.LayoutParams.WRAP_CONTENT:
                        if (heightMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.AT_MOST) {
                            childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
                        } else {
                            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                        }
                        break;
                    default:
                        childHeightSpec = MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY);
                        break;
                }
                usedHeight += MeasureSpec.getSize(childHeightSpec) + params.bottomMargin + params.topMargin;
                measureChild(childView, childWidthSpec, childHeightSpec);
            }
        }
        if (widthMode == MeasureSpec.UNSPECIFIED) {
            widthSize = usedWidth;
        }
        if (heightMode == MeasureSpec.UNSPECIFIED) {
            heightSize = usedHeight;
        }
        setMeasuredDimension(widthSize, heightSize);

        secondaryView = getChildAt(0);
        mainView = getChildAt(1);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        //  初始化 两个页面的布局
        if (secondaryView != null) {
            secondaryView.layout(-secondaryView.getMeasuredWidth(), 0, 0, secondaryView.getMeasuredHeight());
        }

        if (mainView != null) {
            mainView.layout(0, 0, mainView.getMeasuredWidth(), secondaryView.getMeasuredHeight());
        }
    }

    // endregion






    // region 触摸相关
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = (int) event.getRawX();
                break;

            case MotionEvent.ACTION_MOVE:
                int moveX = (int) (event.getRawX() - downX);
                if (secondaryView.getX() < 0 && moveX > 0) {
                    moveX *= rate;
                }
                //  是否 向右滑
                //boolean isScrollerRight = moveX > 0;

                int translateX = endX + moveX;

                // 越界处理
                if (translateX >= secondaryView.getWidth()) {
                    translateX = secondaryView.getWidth();
                }
                if (translateX <= 0) {
                    translateX = 0;
                }
                secondaryView.setTranslationX(translateX);
                mainView.setTranslationX(translateX);
                break;

            case MotionEvent.ACTION_UP:
                endX = (int) mainView.getTranslationX();
                performClick();
                break;
        }
        return true;
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }
    // endregion





    // region 对外的接口


    /**
     * 滑动系数，数字越大 滑动越快
     */
    public void setRate(float rate) {
        this.rate = rate;
    }


    public void switchOpenState(boolean withAnimator ){
        // 此处可以进一步拓展是否启用动画
        switchOpenStateWithAnimator(withAnimator);
    }
    // endregion



    // region 动画相关
    private void switchOpenStateWithAnimator( boolean withAnimator  ) {
        int nowTranslation = (int) secondaryView.getTranslationX();
        boolean is2Open = nowTranslation <= 0 ;
        float wantTransLtion= is2Open ? secondaryView.getWidth() : 0;

        if(!withAnimator){
            secondaryView.setTranslationX(wantTransLtion);
            mainView.setTranslationX(wantTransLtion);
            return;
        }


        AnimatorSet animator = new AnimatorSet();
        ObjectAnimator animator_secondaryView = ObjectAnimator.ofFloat(secondaryView, "translationX", wantTransLtion);
        ObjectAnimator animator_mainView = ObjectAnimator.ofFloat(mainView, "translationX", wantTransLtion);
        animator.setDuration(200);
        animator.setInterpolator(new LinearInterpolator());
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                endX = (int) secondaryView.getTranslationX();
            }

            @Override
            public void onAnimationCancel(Animator animation) {   }

            @Override
            public void onAnimationRepeat(Animator animation) {    }
        });
        animator.play(animator_secondaryView).with(animator_mainView);
        animator.start();
    }

    // endregion

    // region  MarginLayoutParams 参数相关
    public  class LayoutParams extends MarginLayoutParams {

        LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        LayoutParams(int width, int height) {
            super(width, height);
        }

        LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof WithLeftScreenViewGroup.LayoutParams;
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new WithLeftScreenViewGroup.LayoutParams(p);
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new WithLeftScreenViewGroup.LayoutParams(getContext(), attrs);
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new WithLeftScreenViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    // endregion
}
